package com.tanhua.dubbo.server.api;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.tanhua.dubbo.server.enums.IdType;
import com.tanhua.dubbo.server.pojo.Sound;
import com.tanhua.dubbo.server.service.IdService;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

@Service(version = "1.0.0")
@Slf4j
public class SoundApiImpl implements SoundApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${tanhua.default.upload.times}")
    private String uploadTimes;

    @Value("${tanhua.default.download.times}")
    private String downloadTimes;

    private static final String USER_SOUND_UP_TIMES = "USER_SOUND_UP_TIMES";

    private static final String USER_SOUND_DOWN_TIMES = "USER_SOUND_DOWN_TIMES";

    private static final String SOUND_TIMES_PREFIX = "USER_";

    private String getUserSoundTimesKey(Long UserId) {
        return SOUND_TIMES_PREFIX + UserId;
    }

    @Override
    public String saveSound(Sound sound) {
        try {

            //校验
            if (!ObjectUtil.isAllNotEmpty(sound.getUserId(), sound.getSoundUrl())) {
                return null;
            }


            //设置id
            sound.setId(ObjectId.get());
            sound.setSid(this.idService.createId(IdType.SOUND));

            //发布时间
            sound.setCreated(System.currentTimeMillis());

            //保存到Mongodb中
            this.mongoTemplate.save(sound);

            //更新redis
            String hashKey = this.getUserSoundTimesKey(sound.getUserId());
            this.redisTemplate.opsForHash().increment(USER_SOUND_UP_TIMES, hashKey, -1L);

            return sound.getId().toHexString();
        } catch (Exception e) {
            log.error("声音上传失败~ sound = " + sound, e);
        }
        return null;
    }

    @Override
    public String getUploadRemainingTimes(Long userId) {
        //从redis中取出次数
        String hashKey = this.getUserSoundTimesKey(userId);
        Object times = this.redisTemplate.opsForHash().get(USER_SOUND_UP_TIMES, hashKey);

        if (ObjectUtil.isEmpty(times)) {
            //的次数查询mongodb中今天上传
            String today = DateUtil.today();
            Long minDate = DateUtil.parseDateTime(today + " 00:00:00").getTime();
            Long maxDate = DateUtil.parseDateTime(today + " 23:59:59").getTime();

            Query query = Query.query(Criteria.where("userId").is(userId)
                    .andOperator(Criteria.where("created").gte(minDate),
                            Criteria.where("created").lte(maxDate)
                    )
            );
            long count = this.mongoTemplate.count(query, Sound.class);

            if (Convert.toLong(uploadTimes) - count <= 0) {
                count = 0L;
            }

            this.redisTemplate.opsForHash().put(USER_SOUND_UP_TIMES, hashKey, String.valueOf(count));
        }

        return String.valueOf(times);
    }

    @Override
    public String getDownloadRemainingTimes(Long userId) {
        //从redis中取出次数
        String hashKey = this.getUserSoundTimesKey(userId);
        Object times = this.redisTemplate.opsForHash().get(USER_SOUND_DOWN_TIMES, hashKey);

        if (ObjectUtil.isEmpty(times)) {
            //存入今天的次数
            String today = DateUtil.today();
            Long maxDate = DateUtil.parseDateTime(today + " 23:59:59").getTime();
            Long now = System.currentTimeMillis();

            this.redisTemplate.opsForHash().put(USER_SOUND_DOWN_TIMES, hashKey, downloadTimes);
            this.redisTemplate.expire(USER_SOUND_DOWN_TIMES, maxDate - now, TimeUnit.MILLISECONDS);

            return downloadTimes;
        }

        return String.valueOf(times);
    }

    @Override
    public Sound getSound(Long sid, Long userId) {
        //次数减一
        String hashKey = this.getUserSoundTimesKey(userId);
        this.redisTemplate.opsForHash().increment(USER_SOUND_DOWN_TIMES, hashKey, -1L);

        //查询列表
        Query query = Query.query(Criteria.where("sid").is(sid));
        return this.mongoTemplate.findOne(query, Sound.class);

    }
}
